package com.tttt.controller;

import com.tttt.aop.advice.MyHelloService;
import com.tttt.aop.annotation.MockDemoService;
import com.tttt.aop.introduction.MyIntroductionService;
import com.tttt.aop.introduction.UsageTracked;
import com.tttt.aop.proxyproblem.InnerInvokeService;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestAopController {

  @Autowired
  private ApplicationContext applicationContext;

  @RequestMapping("/testAop")
  public String testAop() {
    MyHelloService myHelloService = applicationContext.getBean(MyHelloService.class);
    myHelloService.sayHello("tttt");
    return "OK";
  }

  @RequestMapping("/testAopInnerInvoke")
  public String testAopInnerInvoke() {
    InnerInvokeService innerInvokeService = applicationContext.getBean(
            InnerInvokeService.class);
    // 外部调用，可以触发AOP逻辑
    System.out.println("-----invoke InnerInvokeService.g()-----");
    innerInvokeService.g();
    System.out.println("-------------------------\n");

    System.out.println("-----invoke InnerInvokeService.f()-----");
    // 只有f()会触发AOP逻辑，f()内部对g()的调用不会触发AOP逻辑
    innerInvokeService.f();
    System.out.println("-------------------------\n");

    System.out.println("-----invoke InnerInvokeService.f2()-----");
    // f2()会触发AOP逻辑，同时f2()内部对g()的调用也会触发AOP逻辑
    innerInvokeService.f2();
    System.out.println("-------------------------\n");
    return "OK";
  }

  @RequestMapping("/testAopIntroduction")
  public String testAopIntroduction() {
    UsageTracked usageTracked = applicationContext.getBean(
            "myIntroductionService", UsageTracked.class);
    System.out.println("usage tracked before invoke: " + usageTracked.get());

    MyIntroductionService myIntroductionService = applicationContext.getBean(
            MyIntroductionService.class);
    myIntroductionService.f();

    System.out.println("usage tracked after invoke: " + usageTracked.get());

    return "OK";
  }

  @RequestMapping("testMock")
  public String testMock() {
    MockDemoService mockDemoService = applicationContext.getBean(
            MockDemoService.class);
    System.out.println("mockDemoService.f(): " + mockDemoService.f());
    System.out.println("mockDemoService.g(): " + mockDemoService.g());

    return "OK";
  }
}
